home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr48 / 386p_200.zip / 386MENU.ASM < prev    next >
Assembly Source File  |  1995-01-14  |  29KB  |  1,060 lines

  1.  
  2.         .386p
  3. code32 segment para public use32
  4.        assume cs:code32,ds:code32
  5. include 386power.inc
  6. include chario.inc
  7. include 386video.inc
  8. include 386keyb.inc
  9. include pix.inc
  10.  
  11. ; include common menu definitions
  12. include 386mnu.inc
  13.  
  14. INPUT_ON macro
  15.         mov edi,_CHRMENU2
  16.         mov _CHRFNT,edi
  17.         endm
  18.  
  19. INPUT_OFF macro
  20.         mov edi,_CHRMENU1
  21.         mov _CHRFNT,edi
  22.         endm
  23.  
  24. E_NAME  =4
  25. E_VALUE =8
  26. E_FN    =12
  27. E_MIN   =16
  28. E_MAX   =20
  29. E_STEP  =24
  30.  
  31. ; Header:            text                               menu title
  32. ;
  33. ;       db M_HEADER,t_col,maxwidth,touchngo
  34. ;       dd text_p,x,y
  35. ;
  36. ;   x,y    = initial position IN PIXELS of the upper left border
  37. ;            of this menu, or -1,-1 if the menu manager can freely choose
  38. ;            where popup these.
  39. ;            N.B. if x,y are out of range or the menu manager supports
  40. ;                 popup menu repositioning, these values will be
  41. ;                 modified by the menu manager.
  42. ;   t_col  = column position of entry name
  43. ;   text_p = code32 offset to asciiz string to show starting from
  44. ;            t_col column.
  45. ;   maxwidth = maximum menu width in characters
  46. ;   touchngo:  0=only ESC or an "exit" entry will end this menu
  47. ;              1=AFTER the first SELECTION, end this menu
  48. ;                (useful for the "save game" or "load game" menu)
  49.  
  50. EB_T_COL =1
  51. EB_MAXW  =2
  52. EB_TNG   =3
  53. sho_name:
  54.        mov edx,[ecx*4+ENTRY_ROW]
  55.        mov eax,_VDispX
  56.        mov esi,[ecx*4+ENTRY_DATA]
  57.        mov edi,_ScrBase
  58.        movzx ebp,byte ptr [esi+EB_T_COL]
  59.        add edx,_VDispY
  60.        mov ebx,[esi+E_NAME]
  61.        lea eax,[eax+ebp*8+16]
  62.        call _PutString
  63.        ret
  64.  
  65. name_show:
  66.        ;ecx = current entry index
  67.        pushad
  68.        call sho_name
  69.        popad
  70.        ret
  71.  
  72.  
  73. ; Bar:               text  <-]#############[+>          a "volume level" bar
  74. ;
  75. ;       db M_BAR,t_col,in_col,in_len
  76. ;       dd text_p, value_p, func_p,min, max, step
  77. ;
  78. ;   in_col  = colum position of the "volume level bar"
  79. ;             starting with the <-] character
  80. ;   in_len  = lenght of the "volume bar" (excluding the <-] and [+> characters)
  81. ;   value_p = code32 offset to the variable containing the value to show/set
  82. ;   min     = minimum allowed value
  83. ;   max     = maximum allowed value
  84. ;   func_p  = code32 offset of function to call every time the entry value
  85. ;             is altered (use this for value checking/correction
  86. ;             or to trigger special actions depending on the value )
  87. ;             Function parameters:
  88. ;                       in:
  89. ;                       Segment registers pointing to the usual 386P segments.
  90. ;                       EAX = value "requested by user"
  91. ;                             to set into the variable pointed by value_p
  92. ;                       out:
  93. ;                       EAX = ALLOWED value to store into the variable
  94. ;                             (the menu manager will store it properly)
  95. ;                       IF CARRY SET, REFRESH ALL THE DISPLAYED DATA
  96. ;                       All other registers preserved.
  97. ;
  98. ;   step    = increment/decrement step for the variable pointed by value_p
  99. ;
  100.  
  101. udec: ; bar and unsigned integers
  102. bdec:
  103.        ; ecx = current entry index
  104.        mov esi,[ecx*4+ENTRY_DATA]
  105.        mov ebx,[esi+E_VALUE]
  106.        mov eax,[ebx]
  107.        mov edx,[esi+E_MIN]
  108.        mov ebp,[esi+E_STEP]
  109.        sub eax,edx
  110.        jnb gb_min
  111. cut_down:
  112.        mov eax,edx
  113.        jmp short gb_checked
  114. gb_min:
  115.        sub eax,ebp
  116.        jb cut_down
  117.        add eax,edx
  118.        jmp short gb_checked
  119.  
  120. uinc: ; bar and unsigned integers
  121. binc:
  122.        ; ecx = current entry index
  123.        mov esi,[ecx*4+ENTRY_DATA]
  124.        mov ebx,[esi+E_VALUE]
  125.        mov edx,[esi+E_MAX]
  126.        mov ebp,[esi+E_STEP]
  127.        mov eax,[ebx]
  128.        add eax,ebp
  129.        sub eax,edx
  130.        jb  gb_max
  131.        xor eax,eax
  132. gb_max:
  133.        add eax,edx
  134. gb_checked:
  135.        xor edx,edx
  136.        call [esi+E_FN]
  137.        mov dl,[esi] ; menu type
  138.        mov [ebx],eax
  139.        jnc gb_rfr
  140.        mov eax,ENTRY_DATA
  141.        call m_refresh
  142. gb_rfr:
  143.        jmp dword ptr [edx*4+SHOW] ;chain-call
  144.  
  145. EB_IN_COL =2
  146. EB_IN_LEN =3
  147.  
  148. bstring db 40 dup(0)
  149. bshow:
  150.        ;ecx = current entry index
  151.        push ecx
  152.        call sho_name
  153.        mov edx,[esi+E_VALUE]
  154.        xor ebx,ebx
  155.        mov eax,[edx]
  156.        mov ebp,[esi+E_MIN]
  157.        mov bl,[esi+EB_IN_LEN]
  158.        mov edi,[esi+E_MAX]
  159.        cmp eax,edi
  160.        jbe  low_enough
  161.        mov [edx],edi
  162.        mov eax,edi
  163. low_enough:
  164.        shl ebx,3 ; multiply by 8 to get pixel lenght
  165.        sub eax,ebp
  166.        jnbe high_enough
  167.        mov [edx],ebp  ; round to minimum
  168.        mov eax,ebp    ;
  169. high_enough:
  170.        sub edi,ebp
  171.        mul ebx
  172.        div edi
  173.        ; eax=bar level in pixels
  174.        ; ebx=bar maximum bar level in pixels
  175.        mov edi,offset bstring
  176.        shr ebx,3 ; back to "characters"
  177.        mov edx,eax
  178.        mov byte ptr [edi],ARROW_MINUS
  179. lupp:
  180.        inc edi
  181.        sub eax,8
  182.        jbe outlevel
  183.        mov byte ptr [edi],BAR8
  184.        dec ebx
  185.        jmp short lupp
  186. outlevel:
  187.        add eax,8
  188.        jne goodbar
  189.        mov al,BAR0  ; we have to avoid NULs
  190. goodbar:
  191.        mov [edi],al
  192. empbar:
  193.        inc edi
  194.        dec ebx
  195.        je outbarr
  196.        mov byte ptr [edi],BAR0
  197.        jmp short empbar
  198. outbarr:
  199.        mov edx,[ecx*4+ENTRY_ROW]
  200.        mov word ptr [edi],ARROW_PLUS ; fancy trick, the high byte is NUL
  201.        mov ebx, offset bstring
  202.        mov eax,_VDispX
  203.        add edx,_VDispY
  204.        movzx ebp,byte ptr [esi+EB_IN_COL]
  205.        mov edi,_ScrBase
  206.        lea eax,[eax+ebp*8+16]
  207.        call _PutString
  208.        pop ecx
  209.        ret
  210.  
  211. ; Int:               text  <-]_____________[+>          a 32bit integer value
  212. ;
  213. ;       db M_INT,t_col,in_col,idigits
  214. ;       dd text_p, value_p, func_p, min, max, step
  215. ;
  216. ;       idigits = maximum number of digits including optional sign character
  217.  
  218. EB_IDIGITS=3
  219.  
  220. isel:
  221.       xor eax,eax
  222.       mov edx,[ecx*4+ENTRY_ROW]
  223.       mov esi,[ecx*4+ENTRY_DATA]
  224.       push ecx
  225.       add edx,_VDispY
  226.       xor ecx,ecx
  227.       mov al,[esi+EB_IN_COL]
  228.       mov ebx,[esi+E_VALUE]
  229.       shl eax,3 ; multiply by 8
  230.       mov cl,[esi+EB_IDIGITS]
  231.       push ebx
  232.       INPUT_ON
  233.       add eax,_VDispX
  234.       mov ebx,[ebx]
  235.       mov edi,_ScrBase
  236.       add eax,16
  237.       call _GetInt
  238.       mov eax,ebx ; copy returned value
  239.       INPUT_OFF
  240.       pop ebx
  241.       pop ecx
  242.       jmp icheck
  243.  
  244.  
  245. idec:
  246.        ; ecx = current entry index
  247.        mov esi,[ecx*4+ENTRY_DATA]
  248.        mov ebx,[esi+E_VALUE]
  249.        mov eax,[ebx]
  250.        sub eax,[esi+E_STEP]
  251.        jmp short icheck
  252.  
  253. iinc:
  254.        ; ecx = current entry index
  255.        mov esi,[ecx*4+ENTRY_DATA]
  256.        mov ebx,[esi+E_VALUE]
  257.        mov eax,[ebx]
  258.        add eax,[esi+E_STEP]
  259. icheck:
  260.        cmp eax,[esi+E_MIN]
  261.        jnl gi_min
  262.        mov eax,[esi+E_MIN]
  263. gi_min:
  264.        cmp eax,[esi+E_MAX]
  265.        jle gi_max
  266.        mov eax,[esi+E_MAX]
  267. gi_max:
  268.        call [esi+E_FN]
  269.        mov [ebx],eax
  270.        jnc gi_rfr
  271.        mov eax,ENTRY_DATA
  272.        call m_refresh
  273. gi_rfr:
  274.        ; chain-call to ishow
  275.  
  276. ushow:
  277. ishow:
  278.        ;ecx = current entry index
  279.        push ecx
  280.        call sho_name
  281.        xor ebx,ebx
  282.        mov edx,[ecx*4+ENTRY_ROW]
  283.        xor ecx,ecx
  284.        mov bx,[esi+EB_IN_COL]
  285.        INPUT_ON
  286.        mov eax,_VDispX
  287.        xchg cl,bh ; cl = EB_IDIGITS
  288.        add edx,_VDispY
  289.        mov ebp,[esi+E_VALUE]
  290.        lea eax,[eax+ebx*8+16]
  291.        mov edi,_ScrBase
  292.        mov ebx,ds:[ebp]
  293.        cmp byte ptr [esi],M_INT
  294.        jne is_unsigned
  295.        call _PutInt
  296.        INPUT_OFF
  297.        pop ecx
  298.        ret
  299. is_unsigned:
  300.        call _PutUnsigned
  301.        INPUT_OFF
  302.        pop ecx
  303.        ret
  304.  
  305. ;
  306. ; Unsigned:          text  <-]_____________[+>          a 32bit dword value
  307. ;
  308. ;       db M_UNSIGNED,t_col,in_col,udigits
  309. ;       dd text_p, value_p, func_p, min, max, step
  310. ;
  311. ;        udigits = maximum number of digits (and no sign)
  312.  
  313. ; ushow is included with ishow
  314. ; uinc and udec are the same as bdec and dinc
  315.  
  316. usel:
  317.       xor eax,eax
  318.       mov edx,[ecx*4+ENTRY_ROW]
  319.       mov esi,[ecx*4+ENTRY_DATA]
  320.       push ecx
  321.       add edx,_VDispY
  322.       xor ecx,ecx
  323.       INPUT_ON
  324.       mov al,[esi+EB_IN_COL]
  325.       mov ebx,[esi+E_VALUE]
  326.       shl eax,3 ; multiply by 8
  327.       mov cl,[esi+EB_IDIGITS]
  328.       add eax,_VDispX
  329.       mov ebx,[ebx]
  330.       mov edi,_ScrBase
  331.       add eax,16
  332.       call _GetUnsigned
  333.       mov eax,ebx ; copy returned value
  334.       INPUT_OFF
  335.       pop ecx
  336.       mov ebx,[esi+E_VALUE]
  337.       mov edx,[esi+E_MIN]
  338.       mov ebp,[esi+E_MAX]
  339.       cmp eax,edx
  340.       jnb gb_mgo
  341.       mov eax,edx
  342. gb_mgo:
  343.       cmp eax,ebp
  344.       jb gb_go
  345.       mov eax,ebp
  346. gb_go:
  347.       jmp gb_checked
  348.  
  349. ;
  350. ; Pick_list:         text  <-]_____________[+>          choose from a list
  351. ;
  352. ;       db M_PICK,t_col,in_col,max_item_len
  353. ;       dd text_p, value_p, func_p,picklist_p, picktop
  354. ;
  355. ;       max_item_len = maximum lenght in characters of the strings
  356. ;                      pointed by the "pick list" table
  357. ;                      EVERY string into the pick-list must have this lenght
  358. ;                      (with "padding" spaces if the text is shorter
  359. ;                       and excluding the final NUL from the count).
  360. ;
  361. ;       value_p = pointer to a dword with values ranging
  362. ;                 from 0         (for the first picklist string)
  363. ;                 to   picktop-1 (for the last  picklist string).
  364. ;       picklist_p = pointer to an array of pointers (all code32 offsets)
  365. ;                    to strings describing the "values" you can choose]
  366. E_PICKLIST = 16
  367. E_PICKTOP  = 20
  368.  
  369. pdec:
  370.        ; ecx = current entry index
  371.        mov esi,[ecx*4+ENTRY_DATA]
  372.        mov ebx,[esi+E_VALUE]
  373.        mov eax,[ebx]
  374.        or eax,eax
  375.        jz pick_good
  376.        dec eax
  377.        jmp short pcheck
  378.  
  379. pinc:
  380.        ; ecx = current entry index
  381.        mov esi,[ecx*4+ENTRY_DATA]
  382.        mov ebx,[esi+E_VALUE]
  383.        mov eax,[ebx]
  384.        inc eax
  385. pcheck:
  386.        cmp eax,[esi+E_PICKTOP]
  387.        jb pick_good
  388.        mov eax,[esi+E_PICKTOP]
  389.        dec eax
  390. pick_good:
  391.        call [esi+E_FN]
  392.        mov [ebx],eax
  393.        jnc pick_rfr
  394.        mov eax,ENTRY_DATA
  395.        call m_refresh
  396. pick_rfr:
  397.        ; chain call to pshow
  398. pshow:
  399.        ;ecx = current entry index
  400.        push ecx
  401.        call sho_name
  402.        mov ebx,[esi+E_VALUE]
  403.        mov edx,[ecx*4+ENTRY_ROW]
  404.        movzx ebp,byte ptr [esi+EB_IN_COL]
  405.        INPUT_ON
  406.        mov eax,_VDispX
  407.        add edx,_VDispY
  408.        mov ebx,[ebx]
  409.        mov esi,[esi+E_PICKLIST]
  410.        mov edi,_ScrBase
  411.        lea eax,[eax+ebp*8+16]
  412.        mov ebx,[esi+ebx*4] ; load pointer to string to display
  413.        call _PutString
  414.        INPUT_OFF
  415.        pop ecx
  416.        ret
  417.  
  418. ; String:            text  _____________                string entry
  419. ;
  420. ;       db M_STRING,t_col,in_col,max_string_characters
  421. ;       dd text_p, value_p, sfunc_p
  422. ;
  423. ;       function to call to check string, it is like func_p
  424. ;       but eax is a POINTER to the actual string data
  425. ;       and you cannot modify it!!!!!!!
  426. ssel:
  427.       mov edx,[ecx*4+ENTRY_ROW]
  428.       mov esi,[ecx*4+ENTRY_DATA]
  429.       push ecx
  430.       INPUT_ON
  431.       mov eax,_VDispX
  432.       xor ecx,ecx
  433.       add edx,_VDispY
  434.       movzx ebp,byte ptr[esi+EB_IN_COL]
  435.       mov ebx,[esi+E_VALUE]
  436.       mov cl,[esi+EB_IDIGITS]
  437.       mov edi,_ScrBase
  438.       lea eax,[eax+ebp*8+16]
  439.       call _GetString
  440.       INPUT_OFF
  441.       pop ecx
  442.       mov eax,[esi+E_VALUE]
  443.       call [esi+E_FN]
  444.       jnc str_rfr
  445.        mov eax,ENTRY_DATA
  446.        call m_refresh
  447. str_rfr:
  448.       ; show it
  449. sshow:
  450.        ;ecx = current entry index
  451.        push ecx
  452.        ; first of all, execute a row refresh
  453.        mov esi,DARK6_TEXT+(DARK6_TEXT shl 8)+(DARK6_TEXT shl 16)+(DARK6_TEXT shl 24)
  454.        mov eax,_VDispX
  455.        mov ebx,8
  456.        mov edx,_VDispY
  457.        add eax,16 ; skip the cursor columns
  458.        push ecx
  459.        add edx,[ecx*4+ENTRY_ROW]
  460.        mov edi,_ScrBase
  461.        mov ecx,38*2
  462.        call _Block    ; set background
  463.        pop ecx
  464.        ; menu name
  465.        call sho_name
  466.        ; string value
  467.        INPUT_ON
  468.        mov edx,[ecx*4+ENTRY_ROW]
  469.        movzx ebp,byte ptr [esi+EB_IN_COL]
  470.        mov eax,_VDispX
  471.        add edx,_VDispY
  472.        mov ebx,[esi+E_VALUE]
  473.        lea eax,[eax+ebp*8+16]
  474.        mov edi,_ScrBase
  475.        call _PutString
  476.        INPUT_OFF
  477.        pop ecx
  478.        ret
  479.  
  480. ; Submenu:           text                               call a submenu
  481. ;
  482. ;       db M_MENU,t_col,thru,m_disable
  483. ;       dd text_p, menu_p
  484. ;
  485. ;       menu_p = code32 offset of M_HEADER entry of menu to call
  486. ;                when this entry is clicked.
  487. ;       thru :  0 = when returning, reactivate this menu and refresh screen
  488. ;               1 = when returning, quit this menu automatically.
  489. ;       m_disable: 0 = submenu can be selected
  490. ;                  1 = this submenu cannot be activated
  491.  
  492. EB_THRU    =2
  493. EB_DISABLE =3
  494. msel:
  495.         mov eax,ENTRY_DATA ; get header address
  496.         mov esi,[ecx*4+ENTRY_DATA]
  497.         push eax
  498.         push ecx
  499.         cmp byte ptr [esi+EB_DISABLE],0
  500.         jne old_menu
  501.         mov eax,[esi+E_VALUE]
  502.         call _PopMenu
  503.         cmp byte ptr [esi+EB_THRU],0
  504.         je old_menu
  505.         pop ecx
  506.         pop eax
  507.         pop ebx ; discard return address
  508.         ; menu termination
  509.         popad
  510.         pop _CHRFNT
  511.         ret
  512.  
  513. old_menu:
  514.         pop ecx
  515.         pop eax
  516.         pushad
  517.         call m_refresh
  518.         popad
  519.         ret
  520.  
  521.  
  522. ; Call:           text                               call a subroutine
  523. ;
  524. ;       db M_CALL,t_col,thru,0
  525. ;       dd text_p, procedure_p
  526. ;
  527. ;       procedure_p = code32 offset of code to call
  528. ;                     when this entry is clicked.
  529. ;                     The function assumes cs=_SelCode, ds=es=ss=fs=_SelData
  530. ;                     gs=_SelZero, like the _PopMenu procedure.
  531. ;                     The called procedure must preserve all registers.
  532. ;
  533. csel:
  534.         mov eax,ENTRY_DATA ; get header address
  535.         mov esi,[ecx*4+ENTRY_DATA]
  536.         push _CHRFNT
  537.         push eax
  538.         call dword ptr [esi+E_VALUE]
  539.         cmp byte ptr [esi+EB_THRU],0
  540.         je old_call
  541.         pop eax
  542.         pop _CHRFNT
  543.         pop ebx ; discard return address
  544.         ; menu termination
  545.         popad
  546.         pop _CHRFNT
  547.         ret
  548.  
  549. old_call:
  550.         pop eax
  551.         pop _CHRFNT
  552.         call m_refresh
  553.         ret
  554.  
  555. ; Toggle:            [] text                            boolean entry
  556. ;
  557. ;       db M_TOGGLE,t_col,flag_col,0
  558. ;       dd text_p, bool_p, func_p
  559. ;
  560. ;       flag_col = column position of '[]' on/off character
  561. ;       bool_p   = pointer to BYTE that can be toggled to 0 or to 1
  562. ;                  when clicking on this entry.
  563. ;
  564.         align byte
  565. TOGGLES db FLAG_OFF,0,FLAG_ON,0
  566.  
  567. togg:
  568.        ; ecx = current entry index
  569.        mov esi,[ecx*4+ENTRY_DATA]
  570.        mov ebx,[esi+E_VALUE]
  571.        mov al,[ebx]
  572.        inc al
  573. tcheck:
  574.        and al,1
  575.        call [esi+E_FN]
  576.        mov [ebx],al
  577.        jnc tg_rfr
  578.        mov eax,ENTRY_DATA
  579.        call m_refresh
  580. tg_rfr:
  581.        ; chain call to tshow
  582. tshow:
  583.        ;ecx = current entry index
  584.        push ecx
  585.        ; menu name
  586.        call sho_name
  587.        ; toggle value
  588.        mov edx,[ecx*4+ENTRY_ROW]
  589.        xor ebx,ebx
  590.        mov edi,[esi+E_VALUE]
  591.        movzx ebp,byte ptr [esi+EB_IN_COL]
  592.        mov eax,_VDispX
  593.        mov bl,[edi]
  594.        add edx,_VDispY
  595.        lea eax,[eax+ebp*8+16]
  596.        lea ebx,[ebx*2+TOGGLES]
  597.        mov edi,_ScrBase
  598.        call _PutString
  599.        pop ecx
  600.        ret
  601.  
  602. ; Key:               text  keytext                      keyboard key value
  603. ;
  604. ;       db M_KEY,t_col,key_col,0
  605. ;       dd text_p, key_p, func_p
  606. ;
  607. ;       key_col = column position of TEXT (obtained from _KeyNames)
  608. ;                 describing the key.
  609. ;       key_p   = pointer to BYTE that contains key code
  610. ;
  611.  
  612. ksel:  mov esi,[ecx*4+ENTRY_DATA]
  613.        mov edx,[ecx*4+ENTRY_ROW]
  614.        mov ebx,[esi+E_VALUE]
  615.        mov ebp,[esi+E_FN]
  616.        mov byte ptr [ebx],0
  617.        push eax ; dummy push
  618. ooh_retry:
  619.        pop eax ; discard flags if retried
  620.        call kshowinput
  621.        call entry_refresh
  622.        pushad
  623.        call _ScanKeyb
  624.        mov edi,eax ; clear keyboard table
  625.        mov ecx,32  ;
  626.        xor eax,eax ;
  627.        rep stosd   ;
  628.        popad
  629. wait_release:
  630.        call _ScanKeyb
  631.        mov ebx,eax    ;key table pointer
  632.        mov eax,1      ;key index (0 is NUL, so skip it)
  633. kscanning:
  634.        cmp byte ptr [ebx+eax],KPRESSED
  635.        jne nkukkato
  636.        push ecx
  637.        mov byte ptr [ebx+eax],0
  638.        mov ecx,_KeyNames
  639.        mov ecx,[ecx+eax*4]
  640.        cmp ecx,_NotAKey
  641.        pop ecx
  642.        jne kukkato ; it is a known key
  643. nkukkato:
  644.        inc eax ; increase index
  645.        cmp eax,128
  646.        jb  kscanning
  647.        jmp short wait_release
  648. kukkato:
  649.        call ebp
  650.        pushfd ;save flags
  651.        or eax,eax
  652.        jz ooh_retry ; a NUL entry is not allowed
  653.        mov ebx,[esi+E_VALUE]
  654.        mov [ebx],al
  655.        popfd
  656.        ; chain call to kshow
  657.        jnc ky_rfr
  658.        mov eax,ENTRY_DATA
  659.        call m_refresh
  660. ky_rfr:
  661.  
  662. kshow:
  663.        ;ecx = current entry index
  664.        pushad
  665.        ; first of all, execute a row refresh
  666.        mov esi,DARK6_TEXT+(DARK6_TEXT shl 8)+(DARK6_TEXT shl 16)+(DARK6_TEXT shl 24)
  667.        mov eax,_VDispX
  668.        mov ebx,8
  669.        mov edx,_VDispY
  670.        add eax,16 ; skip the cursor columns
  671.        push ecx
  672.        add edx,[ecx*4+ENTRY_ROW]
  673.        mov edi,_ScrBase
  674.        mov ecx,38*2
  675.        call _Block    ; set background
  676.        pop ecx
  677.        ; menu name
  678.        call sho_name
  679.        ; key's value
  680.        INPUT_ON
  681.        mov esi,[ecx*4+ENTRY_DATA]
  682.        mov ebx,[esi+E_VALUE]
  683.        movzx ebp,byte ptr [esi+EB_IN_COL]
  684.        mov eax,_VDispX
  685.        mov edx,_VDispY
  686.        movzx ebx,byte ptr [ebx]
  687.        mov edi,_ScrBase
  688.        lea eax,[eax+ebp*8+16]
  689.        shl ebx,2
  690.        add edx,[ecx*4+ENTRY_ROW]
  691.        add ebx,_KeyNames
  692.        mov ebx,[ebx]
  693.        call _PutString
  694.        INPUT_OFF
  695.        popad
  696.        ret
  697.  
  698. pressakey db 'press a key',0
  699.  
  700. kshowinput:  ; "show key entry" for input
  701.        ;ecx = current entry index
  702.        pushad
  703.        ; first of all, execute a row refresh
  704.        mov esi,DARK6_TEXT+(DARK6_TEXT shl 8)+(DARK6_TEXT shl 16)+(DARK6_TEXT shl 24)
  705.        mov eax,_VDispX
  706.        mov ebx,8
  707.        mov edx,_VDispY
  708.        add eax,16 ; skip the cursor columns
  709.        push ecx
  710.        add edx,[ecx*4+ENTRY_ROW]
  711.        mov edi,_ScrBase
  712.        mov ecx,38*2
  713.        call _Block    ; set background
  714.        pop ecx
  715.        ; menu name
  716.        call sho_name
  717.        ; "press a key"
  718.        INPUT_ON
  719.        mov esi,[ecx*4+ENTRY_DATA]
  720.        movzx ebp,byte ptr [esi+EB_IN_COL]
  721.        mov eax,_VDispX
  722.        mov edx,_VDispY
  723.        mov edi,_ScrBase
  724.        lea eax,[eax+ebp*8+16]
  725.        add edx,[ecx*4+ENTRY_ROW]
  726.        mov ebx,offset pressakey
  727.        call _PutString
  728.        INPUT_OFF
  729.        popad
  730.        ret
  731.  
  732. ; Exit:              text                               "exit from this menu"
  733. ;
  734. ;       db M_EXIT,t_col,0,0
  735. ;       dd exit_text_p
  736. ;
  737. ;       exit_text_p = pointer to the entry name
  738. ;                     (for example:  'CONTINUE GAME',0)
  739. ;
  740. xsel:
  741.       pop eax ; discard return address
  742.       popad
  743.       pop _CHRFNT
  744.       ret
  745.  
  746. ; End:               etext                              end menu marker
  747. ;                    etext                              with optional text
  748. ;                    ....
  749. ;                    etext
  750. ;
  751. ;
  752. ;       db M_END,t_col,t_lines,0
  753. ;       dd etext_p
  754. ;
  755. ;       t_lines = lines of text/string count of strings pointed by etext_p
  756. ;
  757. ;       etext_p = pointer to  a table of pointers to asciiz text strings
  758. ;                 to show on the bottom of the menu
  759. ;                  if ( etext_p == 0 ) then no text
  760. ;                 For example:
  761. ;                       if etext_p  contains offset menu_usage
  762. ;                       and t_lines contains 4
  763. ;                       and there is:
  764. ;
  765. ;                       menu_usage dd e0,e1,e2,e3,e4,e5
  766. ;
  767. ;                           e0    db ' HOW',0
  768. ;                           e1    db '  MANY',0
  769. ;                           e2    db '   LINES',0
  770. ;                           e3    db 'YOU',0
  771. ;                           e4    db 'WILL',0
  772. ;                           e5    db '  SEE?',0
  773. ;
  774. ;                       You will see on the bottom of the menu:
  775. ;                               HOW
  776. ;                                MANY
  777. ;                                 LINES
  778. ;                              YOU
  779. ;
  780. ;                       (the other strings are not displayed)
  781.  
  782. EB_T_LINES =2
  783.  
  784. eshow: push ecx
  785.        mov edx,[ecx*4+ENTRY_ROW]
  786.        mov eax,_VDispX
  787.        mov esi,[ecx*4+ENTRY_DATA]
  788.        mov edi,_ScrBase
  789.        movzx ebx,byte ptr [esi+EB_T_COL]
  790.        add edx,_VDispY
  791.        movzx ebp,byte ptr [esi+EB_T_LINES]
  792.        lea eax,[eax+ebx*8+16]
  793.        mov esi,[esi+E_NAME]
  794. nxstring:
  795.        mov ebx,[esi]
  796.        add esi,4
  797.        call _PutString
  798.        add edx,8
  799.        dec ebp
  800.        jnz nxstring
  801.        pop ecx
  802.        ret
  803.  
  804. none:
  805.         ret
  806.  
  807. no_more_cursor db '  ',0
  808.  
  809. uup:
  810.         cmp ecx,1
  811.         jbe noo_id
  812.         mov ebp,-1
  813.         jmp short pulisci
  814. dnn:
  815.         cmp ecx,ENTRIES
  816.         jnb noo_id
  817.         mov ebp,+1
  818. pulisci:
  819.         push ecx
  820.         mov eax,0
  821.         mov edx,[ecx*4+ENTRY_ROW]
  822.         mov ebx,8
  823.         mov ecx,4
  824.         mov edi,_ScrBase
  825.         call _TouchBlock
  826.         mov eax,_VDispX
  827.         mov ebx,offset no_more_cursor
  828.         add edx,_VDispY
  829.         mov edi,_ScrBase
  830.         call _PutString
  831.         pop ecx
  832.         add ecx,ebp
  833. noo_id: ret
  834.  
  835. align byte
  836. ;             M_HEADER  M_BAR M_INT M_UNSIGNED M_PICK M_STRING M_MENU    M_CALL    M_TOGGLE M_KEY      M_EXIT     M_END
  837. ENTRY_SIZE db 4*4,      7*4,  7*4,  7*4,       6*4,   4*4,     3*4,      3*4,      4*4,     4*4,       2*4,       2*4
  838. align dword
  839. INCREMENT  dd none,     binc, iinc, uinc,      pinc,  none,    none,     none,     togg,    none,      none,      none
  840. DECREMENT  dd none,     bdec, idec, udec,      pdec,  none,    none,     none,     togg,    none,      none,      none
  841. SELECT     dd none,     none, isel, usel,      none,  ssel,    msel,     csel,     none,    ksel,      xsel,      none
  842. UPP        dd none,     uup,  uup,  uup,       uup,   uup,     uup,      uup,      uup,     uup,       uup,       none
  843. DDN        dd none,     dnn,  dnn,  dnn,       dnn,   dnn,     dnn,      dnn,      dnn,     dnn,       dnn,       none
  844. SHOW       dd name_show,bshow,ishow,ushow,     pshow, sshow,   name_show,name_show,tshow,   kshow,     name_show, eshow
  845.  
  846. ENTRY_DATA dd 25 dup(0)
  847. ENTRY_ROW  dd 25 dup(0)
  848. ENTRIES    dd 0   ; "active" entries (excluding m_header and m_end)
  849.  
  850. align byte
  851. ; empty string to clean screen
  852. zapper     db '                                        ',0
  853.  
  854. tfe db '386MENU: Too few menu entries, need at least a menu exit option',CR,LF,'$'
  855. too_few_entries:
  856.         mov _386Return,offset tfe
  857.         jmp _Exit
  858.  
  859. tmm db '386MENU: Too many menu entries',CR,LF,'$'
  860. too_many_entries:
  861.         mov _386Return,offset tmm
  862.         jmp _Exit
  863.  
  864. touchngo db 0
  865.  
  866. m_refresh: ; refresh menu data structures and screen image
  867.            ; eax= ptr to menu description
  868.         pushad
  869.         mov dl,byte ptr [eax+EB_TNG]
  870.         xor ebp,ebp
  871.         xor ebx,ebx
  872.         mov touchngo,dl
  873.         mov edi,offset ENTRY_DATA
  874.         xor edx,edx
  875. again:
  876.         mov bl,[eax]
  877.         stosd ; data entry position
  878.         mov dl,[ebx+ENTRY_SIZE]
  879.         inc ebp
  880.         add eax,edx
  881.         cmp bl,M_END
  882.         jne again
  883.         cmp ebp,23 ; 25 lines - 2 interlines == 23 entries max.
  884.         ja  too_many_entries
  885.         sub eax,edx ; back to last entry
  886.         xor edx,edx
  887.         sub ebp,2 ; "valid entries" count
  888.         jbe too_few_entries
  889.         mov ebx,22   ; 25 - 1_title_row - 2_interlines
  890.         mov dl,[eax+EB_T_LINES]  ; get lines of ending text
  891.         sub ebx,edx  ; available_entries   - bottom_menu_text
  892.         shl edx,3 ; pixel-lines of text
  893.         push edx ;save lines of text in the end
  894.         ; now calculate menu row positions
  895.         shl ebx,3 ; get value in pixels
  896.         mov ENTRIES,ebp ; save "valid entries" count
  897.         xor edx,edx
  898.         mov eax,ebx       ; divide available lines by entries
  899.         div ebp           ;
  900.         cmp eax,8
  901.         jb too_many_entries ; less than 8 lines for entry? are you nuts?
  902.         mov ebx,eax ; copy
  903.         shr eax,1 ; divide by two
  904.         mov edi,offset ENTRY_ROW
  905.         mov ecx,ENTRIES
  906.         add eax,8 ; add one interline
  907.         mov dword ptr edi [edi],0 ; title position
  908.         add edi,4
  909. row_row:
  910.         stosd
  911.         add eax,ebx
  912.         dec ecx
  913.         jne row_row
  914.         mov eax,200
  915.         pop esi   ; restore pixel-lines of text in menu bottom
  916.         sub eax,esi
  917.         mov [edi],eax ; end text position
  918.         ; menu data setup complete
  919. freshen: ; refresh displayed data
  920.         mov esi,DARK6_TEXT+(DARK6_TEXT shl 8)+(DARK6_TEXT shl 16)+(DARK6_TEXT shl 24)
  921.         mov eax,_VDispX
  922.         mov ecx,40*2
  923.         mov edi,_ScrBase
  924.         mov ebx,25*8
  925.         mov edx,_VDispY
  926.         call _Block    ; set background color
  927.         ; NOW WRITE ENTRIES
  928.         mov edx,ENTRIES
  929.         mov esi,offset ENTRY_DATA
  930.         xor eax,eax
  931.         xor ecx,ecx
  932.         add edx,2 ; header & end
  933. showall:
  934.         mov ebx,[esi]
  935.         add esi,4
  936.         mov  al,[ebx]  ; get menu entry type
  937.         pushad
  938.         call dword ptr [eax*4+SHOW]
  939.         popad
  940.         inc ecx
  941.         dec edx
  942.         jne showall
  943.         xor eax,eax
  944.         xor edx,edx
  945.         mov ecx,40*2
  946.         mov ebx,25*8
  947.         call _TouchBlock
  948.         call _PageFlip1
  949.         ; and now go for menu animation
  950.         popad
  951.         ret
  952.  
  953. il_cursore db POINT0,POINT1,0
  954.  
  955. entry_refresh:
  956.         pushad
  957.         xor eax,eax
  958.         mov ebx,8
  959.         mov edx,[ecx*4+ENTRY_ROW]
  960.         mov ecx,40*2
  961.         call _TouchBlock ; refresh the current entry
  962.         mov eax,_VDispX
  963.         add edx,_VDispY
  964.         mov ebx,offset il_cursore
  965.         mov edi,_ScrBase
  966.         call _PutString  ; write cursor
  967.         call _PageFlip1
  968.         popad
  969.         ret
  970.  
  971.         public _PopMenu
  972.  
  973. _PopMenu:; eax = pointer to menu data
  974.         push _CHRFNT
  975.         pushad
  976.         ; use the "not-input" character set
  977.         INPUT_OFF
  978.         call m_refresh ; refresh/generate the menu data from the description
  979.         mov ecx,1 ; cursor position on first entry
  980. wazoom: call entry_refresh
  981.         call _WaitKey
  982. wazaam:
  983.         xor ebx,ebx
  984.         mov edx,[ecx*4+ENTRY_DATA]
  985.         mov bl,[edx] ; get entry type
  986.         cmp byte ptr [eax+_ESC],KPRESSED  ; WAIT FOR KEY PRESS&RELEASE
  987.         setnz [eax+_ESC]
  988.         je thee_eend
  989.         cmp byte ptr [eax+_LEFT],KPRESSED
  990.         setnz [eax+_LEFT]
  991.         je decc
  992.         cmp byte ptr [eax+_KMINUS],KPRESSED
  993.         setnz [eax+_KMINUS]
  994.         jne nodec
  995. decc:
  996.         call [ebx*4+DECREMENT]
  997.         jmp wazoom
  998. nodec:
  999.         cmp byte ptr [eax+_RIGHT],KPRESSED
  1000.         setnz [eax+_RIGHT]
  1001.         je incc
  1002.         cmp byte ptr [eax+_KPLUS],KPRESSED
  1003.         setnz [eax+_KPLUS]
  1004.         jne noinc
  1005. incc:
  1006.         call [ebx*4+INCREMENT]
  1007.         jmp wazoom
  1008. noinc:  cmp byte ptr [eax+_UP],KPRESSED
  1009.         setnz [eax+_UP]
  1010.         jne noo_uup
  1011.         call [ebx*4+UPP]
  1012.         jmp wazoom
  1013. noo_uup:cmp byte ptr [eax+_DOWN],KPRESSED
  1014.         setnz [eax+_DOWN]
  1015.         jne noo_dnn
  1016.         call [ebx*4+DDN]
  1017.         jmp wazoom
  1018. noo_dnn:cmp byte ptr [eax+_ENTER],KPRESSED
  1019.         setnz [eax+_ENTER]
  1020.         jne wazoom
  1021.         call [ebx*4+SELECT]
  1022.         test touchngo,01
  1023.         jz notouchngo
  1024.         call xsel ; trigger menu exit if this is a touch&go menu
  1025. notouchngo:
  1026.         call entry_refresh
  1027. rescan:
  1028.         call _WaitKey
  1029.         test byte ptr [eax+_ENTER],KPRESSED   ; do this
  1030.         mov byte ptr [eax+_ENTER],0           ;
  1031.         jnz rescan                            ; to avoid key "bounces"
  1032.         jmp wazaam
  1033. thee_eend:
  1034.         popad
  1035.         pop _CHRFNT
  1036.         ret
  1037.  
  1038. ; Look into 386menu.txt for more info.
  1039. ; This function lets you pop-up and "animate" a menu you defined.
  1040. ; you can select and manipolate menu entry data
  1041. ; using the keyboard
  1042. ;
  1043. ;  up/down   = change entry
  1044. ;  enter     = enter a value from the keyboard / trigger entry
  1045. ;              (you can do this only one, then you must use another key
  1046. ;               before you can "select" the entry again
  1047. ;               this is because of the "debouncing" routine)
  1048. ;  left,'-'  = decrease entry's value
  1049. ;  right,'+' = increase entry's value
  1050. ;  esc       = quit menu (only if menu definition data allows it)
  1051. ;
  1052. ; N.B. It supposed that the calling routine will choose the best method
  1053. ;      to save the current screen context before performing the call
  1054. ;      and then it will refresh it on return.
  1055.  
  1056. code32  ends
  1057.         end
  1058.  
  1059.  
  1060.